package com.myjoje.service.system;

import com.myjoje.base.BaseService;
import com.myjoje.bean.system.FileBean;
import com.myjoje.config.shiro.ShiroUtil;
import com.myjoje.jpa.FileJpa;
import com.myjoje.service.tencent.CosService;
import com.myjoje.util.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Optional;

@Service
public class FileService extends BaseService {


    @Value("${app.upload-path}")
    private String uploadPath;

    @Autowired
    private FileJpa fileJpa;

    @Autowired
    private CosService cosService;

    public Message getFileById(String id) {

        return Message.success("请求成功", fileJpa.findById(id));
    }

    @Transactional
    public Object upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        //获取上传文件的文件名
        String filename = multipartFile.getOriginalFilename();

        //文件上传后的路径
        String newFilename = get32UUID() + getFileSuffixName(filename);
        //文件保存：file/年/月
        String basePath = "/" + ShiroUtil.getMd5(getYear()) + "/" + ShiroUtil.getMd5(getMonth());
        String filePath = uploadPath + basePath;
        //文件不存在创建
        File file = new File(filePath);
        if (!file.exists()) {
            try {
                boolean folderCreated = file.mkdirs();
                // if dir wasn't created this time, and doesn't exist
                if (!folderCreated && !file.exists()) {
                    throw new IOException("Unable to create path");
                }
            } catch (SecurityException e) {
                throw new IOException("Unable to create path");
            }
        }
        //Linux和Windows都使用绝对路径
        String realPath = file.getAbsolutePath();
        //保存文件
        File dest = new File(realPath, newFilename);
        multipartFile.transferTo(dest);

        //将上传信息保存到数据库
        FileBean bean = new FileBean();
        bean.setCreateTime(getDateTime());
        bean.setFileName(filename);
        //文件路径
        bean.setFilePath(filePath + "/" + newFilename);
        //访问路径
        bean.setAccessPath(basePath + "/" + newFilename);
        bean.setFileSize(String.valueOf(multipartFile.getSize()));
        bean.setFileType(multipartFile.getContentType());
        String currentUserId = getCurrentUserId();
        bean.setCreateUser(currentUserId);
        fileJpa.save(bean);
        return Message.success("上传成功", bean);
    }


    /**
     * 文件下载
     */
    public void download(HttpServletResponse response, @PathVariable String id) throws Exception {
        Optional<FileBean> optional = fileJpa.findById(id);
        if (optional.isPresent()) {
            FileBean bean = optional.get();
            String fileType = bean.getFileType();
            response.setCharacterEncoding("utf-8");
            //文件类型
            response.setHeader("Content-Type", fileType);
            //文件大小
            response.setHeader("Content-Length", bean.getFileSize());
            //文件名称
            response.setHeader("content-disposition", "attachment;filename="
                    + URLEncoder.encode(bean.getFileName(), "UTF-8"));
            InputStream in;
            if (isNotEmpty(bean.getFilePath())) {
                File file = new File(bean.getFilePath());
                in = new FileInputStream(file);
            } else {
                in = new URL(bean.getAccessPath()).openStream();
            }
            ServletOutputStream out = response.getOutputStream();
            byte[] bt = new byte[1024 * 8];
            int length;
            while ((length = in.read(bt)) != -1) {
                out.write(bt, 0, length);
            }
            in.close();
            out.flush();
            out.close();
        }
    }

    /**
     * 文件删除（本地和数据库都删除）
     */
    @Transactional
    public Object delete(@PathVariable String id) throws Exception {
        Optional<FileBean> optional = fileJpa.findById(id);
        if (optional.isPresent()) {
            FileBean bean = optional.get();
            String filePath = bean.getFilePath();
            //文件路径存在
            if (isNotEmpty(filePath)) {
                File file = new File(filePath);
                if (file.exists() && file.isFile()) {
                    file.delete();
                }
            }else {//删除对象
                cosService.deleteObject(bean.getAccessPath());
            }
            //删除数据库信息
            fileJpa.deleteById(id);
        }
        return Message.success("删除成功");
    }
}
